#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

const int N = 1e4 + 7;
const int MAX = 2e4 + 3;
int fa[N], rsr[N];
// p 用来存储价值向量和牵连向量
pair<int, int> p[MAX];

// dp 数组用于表示花费 i 的价钱所能达到的最大价值
int dp[N];

/**
 * @brief 快读代码
 */
template <class T> inline void read(T &x) {
  x = 0;
  bool flag(0);
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    flag = (ch == '-') ? true : false;
    ch = getchar();
  }

  while (ch >= '0' && ch <= '9') {
    x = (x << 1) + (x << 3) + (ch ^ 48);
    ch = getchar();
  }
  flag ? x = -x : 0;
}

/**
 * @brief 多变量快读
 */
template <class type, class... T> inline void read(type &x, T &... args) {
  read(x), read(args...);
}

int find(int x) { return x == fa[x] ? x : (x = find(fa[x])); }

void merge(int x, int y) {
  int rx = find(x), ry = find(y);
  if (rsr[rx] <= rsr[ry]) {
    fa[rx] = ry;
    rsr[ry] += rsr[rx];
  } else {
    fa[ry] = rx;
    rsr[rx] += rsr[ry];
  }
}

int main() {
  // n 代表云朵数，m 代表牵连数，w 代表剩余价值(价钱)
  int n, m, w;
  // int a, b;
  // int cnt = 0;

  // 读取记录操作
  // cin >> n >> m >> w;
  read(n, m, w);

  // 初始化操作
  for (int i = 1; i <= n; ++i) {
    fa[i] = i;
    rsr[i] = 1;
  }
  for (int i = 1; i <= n + m; ++i) {
    // cin >> a >> b;

    // read(p[i].first), read(p[i].second);
    read(p[i].first, p[i].second);
  }

  // 并查集
  int x, y;
  for (int i = n + 1; i <= n + m; ++i) {
    x = find(p[i].first), y = find(p[i].second);
    if (x == y)
      continue;
    merge(x, y);
  }

  // 将价值向量全部归到父节点, 自身归零
  for (int i = 1; i <= n; ++i) {
    int root = find(i);
    if (i != root) {
      p[root].first += p[i].first;
      p[root].second += p[i].second;
      p[i].first = p[i].second = 0;
    }
  }

  // 缩点后采用0-1背包问题进行解决
  for (int i = 1; i <= n; ++i) {
    for (int j = w; j >= p[i].first; --j) {
      dp[j] = max(dp[j], dp[j - p[i].first] + p[i].second);
    }
  }

  cout << dp[w] << endl;

  return 0;
}